package map.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButton;

import com.toedter.calendar.JDateChooser;

import map.Airport;

import core.ClasseVol;
import core.Graphe;
import core.Ville;
import core.compagnie.CarteFidelite;
import core.dijkstra.DijkstraEngine;
import core.vols.Prix;
import core.vols.VolInstance;
import core.voyageur.Client;
import core.voyageur.Trajet;

import serveur.SimulationServeur;
 
public class FenetreNewTrajet extends JFrame implements ActionListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private int width;
	private JPanel pan;
	private SimulationServeur serveur;
	private JComboBox cbDepart;
	private JComboBox cbArrivee;
	private JComboBox cbDepartVille;
	private JComboBox cbArriveeVille;
	private JComboBox cbClients;
	private JButton buttonProcess;
	private JButton buttonProcessVille;
	private JButton buttonAcheter;
	private JButton buttonAddClient;
	private JRadioButton buttonTrajetSelected;
	private JRadioButton buttonClasseSelected;
	private JPanel northPanel;
	private JPanel centerPanel;
	private JPanel southPanel;
	private ArrayList<Trajet> listTrajets;
	private Hashtable<VolInstance, ClasseVol> classes;
	private ButtonGroup bg;	
	private FenetreNewClient fenetreAddClient;
	private JPanel infosTrajet;
	private JDateChooser dateChooser;
	private JDateChooser dateChooserVille;
		
        public FenetreNewTrajet(SimulationServeur serveur){
                this.width=1000;
        		this.serveur=serveur;
                this.setTitle("Nouveau trajet");
                this.setSize(width, 700);
                this.setLocationRelativeTo(null);               
                
                //Instanciation d'un objet JPanel
                pan = new JPanel(new BorderLayout());       
                //On prévient notre JFrame que ce sera notre JPanel qui sera son contentPane
                this.setContentPane(pan);
                
                cbDepartVille = new JComboBox(serveur.getVilles().values().toArray());
                cbArriveeVille = new JComboBox(serveur.getVilles().values().toArray());
                
                cbDepart = new JComboBox(serveur.getAeroports().values().toArray());
    			cbArrivee = new JComboBox(serveur.getAeroports().values().toArray());
    		
    			
    			buttonProcess = new JButton("Rechercher les vols");
    			buttonProcess.addActionListener(this);
    			
    			buttonProcessVille = new JButton("Rechercher par ville");
    			buttonProcessVille.addActionListener(this);
    			
    			buttonAcheter = new JButton("Acheter");
    			buttonAcheter.setEnabled(true);
    			buttonAcheter.addActionListener(this);
    			
    			buttonTrajetSelected = null;
    			buttonClasseSelected = null;
    			
    			dateChooser = new JDateChooser(new Date());
    			dateChooser.setPreferredSize(new Dimension(120, 32));
    			

    			dateChooserVille = new JDateChooser(new Date());
    			dateChooserVille.setPreferredSize(new Dimension(120, 32));
    			
    			infosTrajet = new JPanel();
    			infosTrajet.setLayout(new BoxLayout(infosTrajet, BoxLayout.Y_AXIS));
    			    			
    			GridLayout layout = new GridLayout(4,1);
    			
    			/* Partie haute :
    			 * Sélection des aéroports de départ et d'arrivée
    			 */
    			northPanel = new JPanel(layout);
    			
    			northPanel.add(new JLabel("Choisissez les aéroports de départ et d'arrivée :"), BorderLayout.NORTH);
    			
    			JPanel selectPanelVille = new JPanel();
    			selectPanelVille.add((new JLabel("De :")));
    			selectPanelVille.add(cbDepartVille);
    			selectPanelVille.add(new JLabel("Vers :"));
    			selectPanelVille.add(cbArriveeVille);
    			selectPanelVille.add(new JLabel("Date :"));
    			selectPanelVille.add(dateChooserVille);
    			selectPanelVille.add(buttonProcessVille);
    			
    			JPanel selectPanel = new JPanel();
    			selectPanel.add((new JLabel("De :")));
    			selectPanel.add(cbDepart);
    			selectPanel.add(new JLabel("Vers :"));
    			selectPanel.add(cbArrivee);
    			selectPanel.add(new JLabel("Date :"));
    			selectPanel.add(dateChooser);
    			selectPanel.add(buttonProcess);
    		
    			northPanel.add(selectPanel);
    			northPanel.add(new JLabel("Choisissez les villes de départ et d'arrivée :"));
    			northPanel.add(selectPanelVille);
    			
    			
    			/* Partie centrale :
    			 * Résultats sous forme de liste de RadioButton
    			 */
    			centerPanel = new JPanel();
    			centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.Y_AXIS));
    			
    			listTrajets = new ArrayList<Trajet>();
    			classes = new Hashtable<VolInstance, ClasseVol>();
    			bg = new ButtonGroup();
    			
    			southPanel = new JPanel();
    			southPanel.setLayout(new BoxLayout(southPanel, BoxLayout.Y_AXIS));
    			
    			if(!serveur.getClients().isEmpty()) {				
    				cbClients = new JComboBox(serveur.getClients().values().toArray());
    			} else cbClients = new JComboBox();
    			
    			JPanel jPClients = new JPanel();
    			jPClients.add(cbClients);
    			
    			buttonAddClient = new JButton("Nouveau client");
    			buttonAddClient.setEnabled(true);
    			buttonAddClient.addActionListener(this);
    			jPClients.add(buttonAddClient);
    			
    			southPanel.add(jPClients);
    			southPanel.add(buttonAcheter);
    	
    			pan.add(northPanel, BorderLayout.NORTH);
    			pan.add(centerPanel, BorderLayout.CENTER);
    			pan.add(southPanel, BorderLayout.SOUTH);
                
                this.setVisible(true);
        }

		public JPanel getPan() {
			return pan;
		}
		
		public void displayTrajet(Airport a, Airport b, boolean clear) {
			if(clear) centerPanel.removeAll();
			centerPanel.add(new JLabel("Liste des trajets possibles :"));
			listTrajets.addAll(serveur.calculateBestTrajet(a, b,dateChooser.getDate()));
			if(listTrajets.isEmpty()) {
				JOptionPane.showMessageDialog(pan, "L'aéroport d'arrivée n'est pas atteignable !");
				return;
			}
			int i=1;
			for(Trajet t : listTrajets) {
				JRadioButton rb = new JRadioButton(t.toString());
				rb.setMargin(new Insets(0, 40, 0, 0));
				rb.setVisible(true);
				rb.addItemListener(new ItemState());
				bg.add(rb);
				centerPanel.add(rb);
				centerPanel.setComponentZOrder(rb, i);
				centerPanel.add(Box.createRigidArea(new Dimension(0,5)));
				i++;
			}					
			pan.validate();
			pan.repaint();
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			// TODO Auto-generated method stub
			if(e.getActionCommand().equals(buttonProcess.getActionCommand())) {
				if(cbDepart.getSelectedItem().equals(cbArrivee.getSelectedItem())) {
					JOptionPane.showMessageDialog(pan, "Vous devez sélectionner deux aéroports différents !", "Attention !", JOptionPane.ERROR_MESSAGE);
				} else {	
					buttonTrajetSelected = null;
					buttonClasseSelected = null;
					listTrajets.clear();
					displayTrajet((Airport)cbDepart.getSelectedItem(),(Airport)cbArrivee.getSelectedItem(), true);
					centerPanel.validate();
				}
			}
			
			if(e.getActionCommand().equals(buttonProcessVille.getActionCommand())) {
				if(cbDepartVille.getSelectedItem().equals(cbArriveeVille.getSelectedItem())) {
					JOptionPane.showMessageDialog(pan, "Vous devez sélectionner deux villes différentes !", "Attention !", JOptionPane.ERROR_MESSAGE);
				} else {
					listTrajets.clear();
					centerPanel.removeAll();
					buttonTrajetSelected = null;
					buttonClasseSelected = null;
					Ville v1 = (Ville)cbDepartVille.getSelectedItem();
					Ville v2 = (Ville)cbArriveeVille.getSelectedItem();
					ArrayList<Airport> airportsDepart = serveur.getPlusProche(v1, 100);
					ArrayList<Airport> airportsArrivee = serveur.getPlusProche(v2, 50);
					for(Airport a : airportsDepart) {
						for(Airport b : airportsArrivee) {
							displayTrajet(a,b,true);
						}
					}
					centerPanel.validate();
					
				}
			}
			
			if(e.getActionCommand().equals(buttonAcheter.getActionCommand())) {
				if(buttonTrajetSelected != null && buttonClasseSelected != null && cbClients.getSelectedItem() != null) {
					Client c = (Client)cbClients.getSelectedItem();
					Trajet t = listTrajets.get(centerPanel.getComponentZOrder(buttonTrajetSelected)-1);
					for(VolInstance v : t.getTrajet()) classes.put(v, ClasseVol.values()[infosTrajet.getComponentZOrder(buttonClasseSelected)]);
					c.acheterBillet(t, classes);
					JOptionPane.showMessageDialog(pan, "Billet acheté !", "Nouveau trajet", JOptionPane.INFORMATION_MESSAGE);
					this.dispose();
				} else {
					JOptionPane.showMessageDialog(pan, "Vous devez sélectionner un trajet et un client !", "Attention !", JOptionPane.ERROR_MESSAGE);
				}
			}
			
			if(e.getActionCommand().equals(buttonAddClient.getActionCommand())) {
				fenetreAddClient = new FenetreNewClient("Nouveau Client", 600, 350, serveur);
				fenetreAddClient.addWindowListener(new WindowState());
			}
			
		}

	private class WindowState implements WindowListener {
		@Override
		public void windowActivated(WindowEvent arg0) {
			// TODO Auto-generated method stub
			
	}

		@Override
		public void windowClosed(WindowEvent arg0) {
			// Si on vient d'ajouter un client on màj la comboBox
			if(arg0.getSource().equals(fenetreAddClient)) {
				cbClients.removeAllItems();
				Iterator<Client> itc = serveur.getClients().values().iterator();
				while(itc.hasNext()) cbClients.addItem(itc.next());
				cbClients.validate();
			}
		}

		@Override
		public void windowClosing(WindowEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void windowDeactivated(WindowEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void windowDeiconified(WindowEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void windowIconified(WindowEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void windowOpened(WindowEvent arg0) {
			// TODO Auto-generated method stub
			
		}
	}

       	
        
        private class ItemState implements ItemListener {

			@Override
			public void itemStateChanged(ItemEvent e) {
				//On met à jours buttonSelected avec le bouton radio sélectionné
				if(e.getStateChange() == ItemEvent.SELECTED) {
					Object item = e.getItem();
					if(item instanceof JRadioButton) {
						if(((JRadioButton)item).getParent().equals(centerPanel)) {
							buttonTrajetSelected = (JRadioButton)item;
							if(cbClients.getSelectedItem() != null) {
								centerPanel.remove(infosTrajet);
								infosTrajet.removeAll();
								Client c = (Client)cbClients.getSelectedItem();
								Trajet t = listTrajets.get(centerPanel.getComponentZOrder(buttonTrajetSelected)-1);
								Prix prix;
								/* Calcul du prix pour chaque classe et ajout d'un RadioButton pour chaque */ 
								ButtonGroup bgClasse = new ButtonGroup();
								Hashtable<VolInstance, ClasseVol> classeTemp = new Hashtable<VolInstance, ClasseVol>();
								int i=0;
								for( ClasseVol classe : ClasseVol.values()) {
									classeTemp.clear();
									prix = new Prix();
									for(VolInstance v : t.getTrajet()) {
										classeTemp.put(v, classe);
									}
									prix.calculate(t.getTrajet(), c, classeTemp);					
									JRadioButton rbClasse = new JRadioButton("Classe "+ classe.toString() +" : "+String.valueOf(new DecimalFormat("0.00").format(prix.getPrix())));
									rbClasse.setMargin(new Insets(0, 80, 0, 0));
									rbClasse.addItemListener(this);
									bgClasse.add(rbClasse);
									infosTrajet.add(rbClasse);
									infosTrajet.setComponentZOrder(rbClasse, i);
									infosTrajet.add(Box.createRigidArea(new Dimension(0,3)));
									buttonClasseSelected = null;
									i++;
								}
							}
							centerPanel.add(infosTrajet, centerPanel.getComponentZOrder(buttonTrajetSelected)+1);
							centerPanel.validate();
						} else if(((JRadioButton)item).getParent().equals(infosTrajet)){
							buttonClasseSelected = (JRadioButton)item;
						}
					}
				}
			}
        	
        }
        
        
	}